const conf = require('../../conf/conf.json')
const fs = require('fs')
const { getModelType } = require('../../util/utils')
const { Display, translateValue, translateGeraldoItem } = require('../../display/general')

let items = null

const loadRawModel = path => {
    return JSON.parse(fs.readFileSync(`${conf.towerDataPath}/${path}`))
}

const parseItemMeta = (item, buff, tower, projectile) => {
    return {
        name: translateGeraldoItem(item.name),
        buffs: Array.isArray(buff) ? buff : [buff],
        towers: Array.isArray(tower) ? tower : [tower],
        projectile: Array.isArray(projectile) ? projectile : [projectile],
        initalQuantity: item.startingQuantity,
        maxQuantity: item.maxQuantity,
        restockRounds: item.roundsToReplenish,
        cost: item.cost,
    }
}

const parseProjectileMeta = (item) => {
    const { parseProjectile } = require('../projectile/parse')
    const b = item.behaviorModels.find(m => getModelType(m) === 'GeraldoCreateProjectileModel')
    return {
        levels: [item.levelUnlockedAt ? item.levelUnlockedAt : 1].concat(b.projectileModelUpgradeAtLevels),
        data: [
            parseItemMeta(item, null, null, parseProjectile(b.projectileModel))
        ].concat(b.projectileModelUpgrades.map(e => parseItemMeta(item, null, null, parseProjectile(e))))
    }
}

const initializeItems = () => {
    const { parseTower } = require('./parse')
    const items = JSON.parse(fs.readFileSync(conf.geraldoItemFile))
    const itemFunctions = {
        "ShootyTurret": item => {
            const rawTower1 = loadRawModel('ShootyTurret/ShootyTurretTower.json')
            const rawTower2 = loadRawModel('ShootyTurret/ShootyTurretTowerV2.json')
            return {
                levels: [1, 13],
                data: [
                    parseItemMeta(item, null, parseTower(rawTower1)),
                    parseItemMeta(item, null, parseTower(rawTower2))
                ]
            }
        },
        "StackOfOldNails": parseProjectileMeta,
        "CreepyIdol": item => {
            const rawTower1 = loadRawModel('CreepyIdol/CreepyIdolTower.json')
            const rawTower2 = loadRawModel('CreepyIdol/CreepyIdolTowerV2.json')
            const rawTower3 = loadRawModel('CreepyIdol/CreepyIdolTowerV3.json')
            return {
                levels: [1, 12, 18],
                data: [
                    parseItemMeta(item, null, parseTower(rawTower1)),
                    parseItemMeta(item, null, parseTower(rawTower2)),
                    parseItemMeta(item, null, parseTower(rawTower3)),
                ]
            }
        },
        "JarOfPickles": item => {
            const b = item.behaviorModels.find(m => getModelType(m) === 'JarOfPicklesBehaviorModel')
            const result = {
                levels: [item.levelUnlockedAt ? item.levelUnlockedAt : 1],
                data: [
                    parseItemMeta(item, {
                        name: translateValue('pickles', 'pickles'),
                        cooldownMultiplier: Display.multiplierPercent(1 / b.attackSpeedScale),
                        additionalDamage: Display.additive(b.damageIncrease),
                        rounds: b.rounds
                    })
                ]
            }
            if (b.bonusFortDamage) {
                result.levels.push(b.bonusFortDamageAt)
                result.data.push(
                    parseItemMeta(item, {
                        name: translateValue('pickles', 'pickles'),
                        cooldownMultiplier: Display.multiplierPercent(1 / b.attackSpeedScale),
                        additionalDamage: Display.additive(b.damageIncrease),
                        additionalDamageForFortified: Display.additive(b.bonusFortDamage),
                        rounds: b.rounds
                    })
                )
            }
            if (b.bonusFortDamageV2) {
                result.levels.push(b.bonusFortDamageAtV2)
                result.data.push(
                    parseItemMeta(item, {
                        name: translateValue('pickles', 'pickles'),
                        cooldownMultiplier: Display.multiplierPercent(1 / b.attackSpeedScale),
                        additionalDamage: Display.additive(b.damageIncrease),
                        additionalDamageForFortified: Display.additive(b.bonusFortDamageV2),
                        rounds: b.rounds
                    })
                )
            }
            return result
        },
        "RareQuincyActionFigure": item => {
            const rawTower = loadRawModel('RareQuincyActionFigure/RareQuincyActionFigureTower.json')
            return {
                levels: [2],
                data: [parseItemMeta(item, null, parseTower(rawTower))]
            }
        },
        "SeeInvisibilityPotion": item => {
            const b = item.behaviorModels.find(m => getModelType(m) === 'SeeInvisibilityPotionBehaviorModel')
            const result = {
                levels: [item.levelUnlockedAt ? item.levelUnlockedAt : 1],
                data: [
                    parseItemMeta(item, {
                        name: translateValue('invisibilityPotion', 'see invisibility potion'),
                        mutationId: Display.mutationId(b.EffectMutator.id),
                        rounds: b.rounds
                    })
                ]
            }
            if (b.upgradedRangeScale > 1 || b.roundsUpgradedTo > b.rounds) {
                result.levels.push(b.upgradeV2At)
                result.data.push(
                    parseItemMeta(item, {
                        name: translateValue('invisibilityPotion', 'see invisibility potion'),
                        mutationId: Display.mutationId(b.EffectMutator.id),
                        rangeMultiplier: b.upgradedRangeScale > 1 ? Display.multiplierPercent(b.upgradedRangeScale) : null,
                        rounds: b.roundsUpgradedTo
                    })
                )
            }
            if (b.bonusCamoDamage > 0) {
                result.levels.push(b.upgradeV3At)
                result.data.push(
                    parseItemMeta(item, {
                        name: translateValue('invisibilityPotion', 'see invisibility potion'),
                        mutationId: Display.mutationId(b.EffectMutator.id),
                        rangeMultiplier: b.upgradedRangeScale > 1 ? Display.multiplierPercent(b.upgradedRangeScale) : null,
                        additionalDamageForCamo: Display.additive(b.bonusCamoDamage),
                        rounds: b.roundsUpgradedTo
                    })
                )
            }
            return result
        },
        "TubeOfAmazoGlue": parseProjectileMeta,
        "SharpeningStone": item => {
            const b = item.behaviorModels.find(m => getModelType(m) === 'SharpeningStoneBehaviorModel')
            const result = {
                levels: [item.levelUnlockedAt ? item.levelUnlockedAt : 1],
                data: [
                    parseItemMeta(item, {
                        name: translateValue('sharpeningStone', 'sharpening stone'),
                        mutationId: Display.mutationId(b.Mutator.id),
                        additionalPierce: Display.additive(b.pierceIncrease),
                        rounds: b.rounds
                    })
                ]
            }
            if (b.bonusPierce > 0) {
                result.levels.push(b.bonusPierceAtLevel)
                result.data.push(
                    parseItemMeta(item, {
                        name: translateValue('sharpeningStone', 'sharpening stone'),
                        mutationId: Display.mutationId(b.MutatorGreater.id),
                        additionalPierce: Display.additive(b.pierceIncrease + b.bonusPierce),
                        rounds: b.rounds
                    })
                )
            }
            return result
        },
        "WornHerosCape": item => {
            return {
                levels: [6],
                data: [parseItemMeta(item)]
            }
        },
        "BladeTrap": parseProjectileMeta,
        "BottleHotSauce": item => {
            const rawTower1 = loadRawModel('HotSauceCreature/HotSauceCreatureTower.json')
            const rawTower2 = loadRawModel('HotSauceCreature/HotSauceCreatureTowerV2.json')
            return {
                levels: [8, 16],
                data: [
                    parseItemMeta(item, null, parseTower(rawTower1)),
                    parseItemMeta(item, null, parseTower(rawTower2))
                ]
            }
        },
        "Fertilizer": item => {
            const b = item.behaviorModels.find(m => getModelType(m) === 'FertilizerBehaviorModel')
            return {
                levels: [item.levelUnlockedAt],
                data: [parseItemMeta(item, {
                    name: translateValue('fertilizer', 'fertilizer'),
                    mutationId: Display.mutationId(b.Mutator.id),
                    cashMultiplier: Display.additivePercent(b.cashScale - 1),
                    rounds: b.rounds
                })]
            }
        },
        "PetRabbit": item => {
            const rawTower = loadRawModel('WererabbitTower/WererabbitTower.json')
            return {
                levels: [10],
                data: [parseItemMeta(item, null, parseTower(rawTower))]
            }
        },
        "RejuvPotion": item => {
            return {
                levels: [11],
                data: [parseItemMeta(item)]
            }
        },
        "GenieBottle": item => {
            const rawTower1 = loadRawModel('GenieBottle/GenieBottleTower.json')
            const rawTower2 = loadRawModel('GenieBottle/GenieBottleTowerV2.json')
            return {
                levels: [12, 18],
                data: [
                    parseItemMeta(item, null, parseTower(rawTower1)),
                    parseItemMeta(item, null, parseTower(rawTower2))
                ]
            }
        },
        "ParagonPowerTotem": item => {
            const rawTower = loadRawModel('ParagonTotem-ParagonTotem/ParagonTotem-ParagonTotem.json')
            return {
                levels: [20],
                data: [parseItemMeta(item, null, parseTower(rawTower))]
            }
        }
    }
    const result = {}
    items.forEach(e => {
        result[`Geraldo${e.name}`] = itemFunctions[`${e.name}`](e)
    })
    return result
}

const parseGeraldoItems = (tier) => {
    items = items || initializeItems()
    const result = []
    for (const key in items) {
        const item = items[key]
        if (!item || tier < item.levels[0]) continue
        result.push(item.data[item.levels.findLastIndex(e => e <= tier)])
    }
    return result
}

module.exports = {
    parseGeraldoItems
}